# 8.4 torchtext简介 本节我们来介绍PyTorch官方用于自然语言处理(NLP)的工具包torchtext。自然语言处理也是深度学习的一大应用场景,近年来随着大规模预训练模型的应用,深度学习在人机对话、机器翻译等领域的取得了非常好的效果,也使得NLP相关的深度学习模型获得了越来越多的关注。 由于NLP和CV在数据预处理中的不同,因此NLP的工具包torchtext和torchvision等CV相关工具包也有一些功能上的差异,如: - 数据集(dataset)定义方式不同 - 数据预处理工具 - 没有琳琅满目的model zoo 本节介绍参考了[atnlp的Github](https://github.com/atnlp/torchtext-summary),在此致谢! ## 8.4.1 torchtext的主要组成部分 torchtext可以方便的对文本进行预处理,例如截断补长、构建词表等。torchtext主要包含了以下的主要组成部分: - 数据处理工具 torchtext.data.functional、torchtext.data.utils - 数据集 torchtext.data.datasets - 词表工具 torchtext.vocab - 评测指标 torchtext.metrics ## 8.4.2 torchtext的安装 torchtext可以直接使用pip进行安装: ```bash pip install torchtext ``` ## 8.4.3 构建数据集 - **Field及其使用** Field是torchtext中定义数据类型以及转换为张量的指令。`torchtext` 认为一个样本是由多个字段(文本字段,标签字段)组成,不同的字段可能会有不同的处理方式,所以才会有 `Field` 抽象。定义Field对象是为了明确如何处理不同类型的数据,但具体的处理则是在Dataset中完成的。下面我们通过一个例子来简要说明一下Field的使用: ```python tokenize = lambda x: x.split() TEXT = data.Field(sequential=True, tokenize=tokenize, lower=True, fix_length=200) LABEL = data.Field(sequential=False, use_vocab=False) ``` 其中: ​ sequential设置数据是否是顺序表示的; ​ tokenize用于设置将字符串标记为顺序实例的函数 ​ lower设置是否将字符串全部转为小写; ​ fix_length设置此字段所有实例都将填充到一个固定的长度,方便后续处理; ​ use_vocab设置是否引入Vocab object,如果为False,则需要保证之后输入field中的data都是numerical的 构建Field完成后就可以进一步构建dataset了: ```python from torchtext import data def get_dataset(csv_data, text_field, label_field, test=False): fields = [("id", None), # we won't be needing the id, so we pass in None as the field ("comment_text", text_field), ("toxic", label_field)] examples = [] if test: # 如果为测试集,则不加载label for text in tqdm(csv_data['comment_text']): examples.append(data.Example.fromlist([None, text, None], fields)) else: for text, label in tqdm(zip(csv_data['comment_text'], csv_data['toxic'])): examples.append(data.Example.fromlist([None, text, label], fields)) return examples, fields ``` 这里使用数据csv_data中有"comment_text"和"toxic"两列,分别对应text和label。 ```python train_data = pd.read_csv('train_toxic_comments.csv') valid_data = pd.read_csv('valid_toxic_comments.csv') test_data = pd.read_csv("test_toxic_comments.csv") TEXT = data.Field(sequential=True, tokenize=tokenize, lower=True) LABEL = data.Field(sequential=False, use_vocab=False) # 得到构建Dataset所需的examples和fields train_examples, train_fields = get_dataset(train_data, TEXT, LABEL) valid_examples, valid_fields = get_dataset(valid_data, TEXT, LABEL) test_examples, test_fields = get_dataset(test_data, TEXT, None, test=True) # 构建Dataset数据集 train = data.Dataset(train_examples, train_fields) valid = data.Dataset(valid_examples, valid_fields) test = data.Dataset(test_examples, test_fields) ``` 可以看到,定义Field对象完成后,通过get_dataset函数可以读入数据的文本和标签,将二者(examples)连同field一起送到torchtext.data.Dataset类中,即可完成数据集的构建。使用以下命令可以看下读入的数据情况: ```python # 检查keys是否正确 print(train[0].__dict__.keys()) print(test[0].__dict__.keys()) # 抽查内容是否正确 print(train[0].comment_text) ``` - **词汇表(vocab)** 在NLP中,将字符串形式的词语(word)转变为数字形式的向量表示(embedding)是非常重要的一步,被称为Word Embedding。这一步的基本思想是收集一个比较大的语料库(尽量与所做的任务相关),在语料库中使用word2vec之类的方法构建词语到向量(或数字)的映射关系,之后将这一映射关系应用于当前的任务,将句子中的词语转为向量表示。 在torchtext中可以使用Field自带的build_vocab函数完成词汇表构建。 ```python TEXT.build_vocab(train) ``` - **数据迭代器** 其实就是torchtext中的DataLoader,看下代码就明白了: ```python from torchtext.data import Iterator, BucketIterator # 若只针对训练集构造迭代器 # train_iter = data.BucketIterator(dataset=train, batch_size=8, shuffle=True, sort_within_batch=False, repeat=False) # 同时对训练集和验证集进行迭代器的构建 train_iter, val_iter = BucketIterator.splits( (train, valid), # 构建数据集所需的数据集 batch_sizes=(8, 8), device=-1, # 如果使用gpu,此处将-1更换为GPU的编号 sort_key=lambda x: len(x.comment_text), # the BucketIterator needs to be told what function it should use to group the data. sort_within_batch=False ) test_iter = Iterator(test, batch_size=8, device=-1, sort=False, sort_within_batch=False) ``` torchtext支持只对一个dataset和同时对多个dataset构建数据迭代器。 - **使用自带数据集** 与torchvision类似,torchtext也提供若干常用的数据集方便快速进行算法测试。可以查看[官方文档](https://pytorch.org/text/stable/datasets.html)寻找想要使用的数据集。 ## 8.4.4 评测指标(metric) NLP中部分任务的评测不是通过准确率等指标完成的,比如机器翻译任务常用BLEU (bilingual evaluation understudy) score来评价预测文本和标签文本之间的相似程度。torchtext中可以直接调用torchtext.data.metrics.bleu_score来快速实现BLEU,下面是一个官方文档中的一个例子: ```python from torchtext.data.metrics import bleu_score candidate_corpus = [['My', 'full', 'pytorch', 'test'], ['Another', 'Sentence']] references_corpus = [[['My', 'full', 'pytorch', 'test'], ['Completely', 'Different']], [['No', 'Match']]] bleu_score(candidate_corpus, references_corpus) ``` ``` 0.8408964276313782 ``` ## 8.4.5 其他 值得注意的是,由于NLP常用的网络结构比较固定,torchtext并不像torchvision那样提供一系列常用的网络结构。模型主要通过torch.nn中的模块来实现,比如torch.nn.LSTM、torch.nn.RNN等。 **备注:** 对于文本研究而言,当下Transformer已经成为了绝对的主流,因此PyTorch生态中的[HuggingFace](https://huggingface.co/)等工具包也受到了越来越广泛的关注。这里强烈建议读者自行探索相关内容,可以写下自己对于HuggingFace的笔记,如果总结全面的话欢迎pull request,充实我们的课程内容。 **本节参考** - [torchtext官方文档](https://pytorch.org/text/stable/index.html) - [atnlp/torchtext-summary](https://github.com/atnlp/torchtext-summary)